<template>
  <div class="chart-container">
    <div
      ref="chartRef"
      class="chart-renderer"
      :style="{ width: width, height: height }"
    />
    <!-- 自定义垂直滚动条 -->
    <div v-if="needScroll" class="custom-scrollbar">
      <div class="scrollbar-track">
        <div
          class="scrollbar-thumb"
          :style="scrollbarThumbStyle"
          @mousedown="startDrag"
        ></div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch, nextTick, computed } from 'vue'
import * as echarts from 'echarts'
import type { RealtimeData, Channel } from '@/types/chart'
import { addMarkPoints } from '@/utils/chartGenerator'

interface Props {
  option: echarts.EChartsOption
  data?: RealtimeData
  selectedChannels?: Channel[]
  width?: string
  height?: string
  markPoints?: {
    channelIndex: number
    points: Array<{ coord: [string | number, number] }>
    type: 'support' | 'suspension'
  }[]
  scrollPosition?: number // 滚动位置 (0-100)
}

const props = withDefaults(defineProps<Props>(), {
  width: '100%',
  height: '100%',
  data: () => ({
    X: [],
    X1: [],
    X2: [],
    Y1: [],
    Y2: [],
    SpeedList: [],
    MoHaoList1: [],
    MoHaoList2: [],
    fVot: [],
    fPressList1: [],
    fPressList2: [],
    fVibrationList1: [],
    fVibrationList2: []
  }),
  selectedChannels: () => [],
  markPoints: () => [],
  scrollPosition: 0
})

const emit = defineEmits<{
  chartReady: [chart: echarts.ECharts]
  dataZoom: [params: any]
  click: [params: any]
  scrollChange: [position: number] // 滚动位置变化事件
  pauseRender: [pause: boolean] // 暂停/恢复渲染事件
}>()

const chartRef = ref<HTMLElement>()
let chartInstance: echarts.ECharts | null = null

// 滚动相关
const maxVisibleGrids = 3
const scrollTimer = ref<number | null>(null) // 滚动定时器
const totalGrids = computed(() => {
  if (!props.selectedChannels) return 0

  // 计算实际的 Grid 数量（合并的通道算一个）
  const channelGroups: { [key: string]: boolean } = {}
  let count = 0

  props.selectedChannels.forEach(channel => {
    if (channel.name === 'X1工支' || channel.name === 'X2非支') {
      if (!channelGroups['拉出值']) {
        channelGroups['拉出值'] = true
        count++
      }
    } else if (channel.name === '接触力1' || channel.name === '接触力2') {
      if (!channelGroups['接触力']) {
        channelGroups['接触力'] = true
        count++
      }
    } else if (channel.name === '加速度1' || channel.name === '加速度2') {
      if (!channelGroups['加速度']) {
        channelGroups['加速度'] = true
        count++
      }
    } else {
      count++
    }
  })

  return count
})

const needScroll = computed(() => totalGrids.value > maxVisibleGrids)

// 滚动条样式
const scrollbarThumbStyle = computed(() => {
  if (!needScroll.value) return {}

  const thumbHeight = (maxVisibleGrids / totalGrids.value) * 100
  const thumbTop = (props.scrollPosition || 0)

  return {
    height: `${thumbHeight}%`,
    top: `${thumbTop}%`
  }
})

// 滚动条拖拽
const isDragging = ref(false)
const dragStartY = ref(0)
const dragStartScroll = ref(0)

const startDrag = (e: MouseEvent) => {
  isDragging.value = true
  dragStartY.value = e.clientY
  dragStartScroll.value = props.scrollPosition || 0

  document.addEventListener('mousemove', onDrag)
  document.addEventListener('mouseup', stopDrag)
  e.preventDefault()
}

const onDrag = (e: MouseEvent) => {
  if (!isDragging.value) return

  const trackHeight = chartRef.value?.clientHeight || 1
  const deltaY = e.clientY - dragStartY.value
  const deltaPercent = (deltaY / trackHeight) * 100

  const maxScroll = ((totalGrids.value - maxVisibleGrids) / totalGrids.value) * 100
  const newScroll = Math.max(0, Math.min(maxScroll, dragStartScroll.value + deltaPercent))

  emit('scrollChange', newScroll)
}

const stopDrag = () => {
  isDragging.value = false
  document.removeEventListener('mousemove', onDrag)
  document.removeEventListener('mouseup', stopDrag)
}

// 鼠标滚轮事件
const handleWheel = (e: WheelEvent) => {
  if (!needScroll.value) return

  e.preventDefault()

  // 滚动开始时暂停渲染
  emit('pauseRender', true)

  // 清除之前的定时器
  if (scrollTimer.value !== null) {
    clearTimeout(scrollTimer.value)
  }

  const delta = e.deltaY > 0 ? 5 : -5 // 每次滚动5%
  const maxScroll = ((totalGrids.value - maxVisibleGrids) / totalGrids.value) * 100
  const newScroll = Math.max(0, Math.min(maxScroll, (props.scrollPosition || 0) + delta))

  emit('scrollChange', newScroll)

  // 设置新的定时器，0.5秒后恢复渲染
  scrollTimer.value = window.setTimeout(() => {
    emit('pauseRender', false)
    scrollTimer.value = null
  }, 500)
}

// 初始化图表
const initChart = () => {
  if (!chartRef.value) return

  chartInstance = echarts.init(chartRef.value)

  // 禁用ECharts的动画以提高性能
  chartInstance.setOption({
    animation: false
  })

  updateChart()

  // 绑定事件
  chartInstance.on('datazoom', (params) => {
    emit('dataZoom', params)
  })

  chartInstance.on('click', (params) => {
    emit('click', params)
  })

  emit('chartReady', chartInstance)
}

// 轻量防抖，只避免同一帧内的重复渲染
let updateTimer: number | null = null

// 更新图表
const updateChart = () => {
  if (!chartInstance) return

  // 使用requestAnimationFrame确保在下一帧渲染，避免同一帧多次更新
  if (updateTimer !== null) {
    cancelAnimationFrame(updateTimer)
  }

  updateTimer = requestAnimationFrame(() => {
    if (!chartInstance) return

    const option = { ...props.option }

    // 更新数据
    if (props.data && props.selectedChannels) {
      updateSeriesData(option)
    }

    // 添加标记点
    if (props.markPoints) {
      addMarkPointsToOption(option)
    }

    // 使用增量更新以提高性能
    chartInstance.setOption(option, {
      notMerge: false,  // 增量更新，不完全替换
      replaceMerge: ['series'] // 只替换系列数据
    })

    updateTimer = null
  })
}

// 更新系列数据
const updateSeriesData = (option: echarts.EChartsOption) => {
  const series = option.series as any[]
  if (!series || !props.selectedChannels) return

  // 创建通道分组映射，与 chartGenerator.ts 的逻辑保持一致
  const channelGroups: { [key: string]: Channel[] } = {}
  const processedChannels: Channel[] = []

  props.selectedChannels.forEach((channel) => {
    if (channel.name === 'X1工支' || channel.name === 'X2非支') {
      // 将工支和非支归为一组
      if (!channelGroups['拉出值']) {
        channelGroups['拉出值'] = []
        processedChannels.push({
          name: '拉出值',
          unit: 'mm',
          min: -600,
          max: 600,
          color: '#91CC75',
          selected: true,
          type: 'line'
        })
      }
      channelGroups['拉出值'].push(channel)
    } else if (channel.name === '接触力1' || channel.name === '接触力2') {
      // 将接触力1和接触力2归为一组
      if (!channelGroups['接触力']) {
        channelGroups['接触力'] = []
        processedChannels.push({
          name: '接触力',
          unit: 'N',
          min: 0,
          max: 300,
          color: '#73C0DE',
          selected: false,
          type: 'line'
        })
      }
      channelGroups['接触力'].push(channel)
    } else if (channel.name === '加速度1' || channel.name === '加速度2') {
      // 将加速度1和加速度2归为一组
      if (!channelGroups['加速度']) {
        channelGroups['加速度'] = []
        processedChannels.push({
          name: '加速度',
          unit: 'm/s²',
          min: 0,
          max: 50,
          color: '#3BA272',
          selected: false,
          type: 'line'
        })
      }
      channelGroups['加速度'].push(channel)
    } else {
      processedChannels.push(channel)
    }
  })

  let seriesIndex = 0
  processedChannels.forEach((channel, channelIndex) => {
    // 更新X轴数据
    if (option.xAxis && Array.isArray(option.xAxis) && (option.xAxis as any[])[channelIndex]) {
      (option.xAxis as any[])[channelIndex].data = props.data?.X || []
    }

    if (channel.name === '拉出值' && channelGroups['拉出值']) {
      // 拉出值组：为工支和非支设置数据
      const groupChannels = channelGroups['拉出值']
      groupChannels.forEach((groupChannel) => {
        if (series[seriesIndex]) {
          series[seriesIndex].data = groupChannel.name === 'X1工支'
            ? (props.data?.X1 || [])
            : (props.data?.X2 || [])
        }
        seriesIndex++
      })
    } else if (channel.name === '接触力' && channelGroups['接触力']) {
      // 接触力组：为接触力1和接触力2设置数据
      const groupChannels = channelGroups['接触力']
      groupChannels.forEach((groupChannel) => {
        if (series[seriesIndex]) {
          series[seriesIndex].data = groupChannel.name === '接触力1'
            ? (props.data?.fPressList1 || [])
            : (props.data?.fPressList2 || [])
        }
        seriesIndex++
      })
    } else if (channel.name === '加速度' && channelGroups['加速度']) {
      // 加速度组：为加速度1和加速度2设置数据
      const groupChannels = channelGroups['加速度']
      groupChannels.forEach((groupChannel) => {
        if (series[seriesIndex]) {
          series[seriesIndex].data = groupChannel.name === '加速度1'
            ? (props.data?.fVibrationList1 || [])
            : (props.data?.fVibrationList2 || [])
        }
        seriesIndex++
      })
    } else if (channel.name === '导高') {
      // 导高需要两条线
      if (series[seriesIndex]) {
        series[seriesIndex].data = props.data?.Y1 || []
      }
      seriesIndex++
      if (series[seriesIndex]) {
        series[seriesIndex].data = (props.data as any)?.Y2 || []
      }
      seriesIndex++
    } else if (channel.name === '磨耗表') {
      // 磨耗表需要两条线
      if (series[seriesIndex]) {
        series[seriesIndex].data = props.data?.MoHaoList1 || []
      }
      seriesIndex++
      if (series[seriesIndex]) {
        series[seriesIndex].data = (props.data as any)?.MoHaoList2 || []
      }
      seriesIndex++
    } else {
      // 其他通道单线
      if (series[seriesIndex]) {
        switch (channel.name) {
          case '速度':
            series[seriesIndex].data = props.data?.SpeedList || []
            break
          case '网压':
            series[seriesIndex].data = props.data?.fVot || []
            break
          default:
            series[seriesIndex].data = []
        }
      }
      seriesIndex++
    }
  })
}

// 添加标记点到配置
const addMarkPointsToOption = (option: echarts.EChartsOption) => {
  props.markPoints?.forEach(({ channelIndex, points, type }) => {
    addMarkPoints(option, channelIndex, points, type)
  })
}

// 调整图表尺寸
const resizeChart = () => {
  if (chartInstance) {
    nextTick(() => {
      chartInstance?.resize()
    })
  }
}

// 监听配置变化 - 直接响应
watch(() => props.option, () => {
  updateChart()
}, { deep: true })

// 监听数据变化 - 直接响应WebSocket频率，减少不必要的深度比较
watch(() => props.data, (newData, oldData) => {
  // 只进行简单的长度检查，避免复杂比较
  if (newData && oldData && newData.X.length === oldData.X.length) {
    // 如果长度相同，只检查最后几个数据点是否变化
    const lastNewItems = newData.X.slice(-3)
    const lastOldItems = oldData.X.slice(-3)
    if (JSON.stringify(lastNewItems) === JSON.stringify(lastOldItems)) {
      return // 数据没有实质变化，跳过更新
    }
  }

  // 直接更新，跟随WebSocket接收频率
  updateChart()
}, { deep: false }) // 使用浅比较提高性能

// 监听标记点变化 - 直接响应
watch(() => props.markPoints, () => {
  updateChart()
}, { deep: true })

// 暴露方法给父组件
defineExpose({
  resizeChart,
  getChart: () => chartInstance
})

onMounted(() => {
  initChart()

  // 监听窗口大小变化
  window.addEventListener('resize', resizeChart)

  // 监听鼠标滚轮事件（用于图表滚动）
  if (chartRef.value) {
    chartRef.value.addEventListener('wheel', handleWheel, { passive: false })
  }
})

onUnmounted(() => {
  if (chartInstance) {
    chartInstance.dispose()
    chartInstance = null
  }

  window.removeEventListener('resize', resizeChart)

  // 移除滚轮事件监听
  if (chartRef.value) {
    chartRef.value.removeEventListener('wheel', handleWheel)
  }

  // 清理拖拽事件
  document.removeEventListener('mousemove', onDrag)
  document.removeEventListener('mouseup', stopDrag)

  // 清理滚动定时器
  if (scrollTimer.value !== null) {
    clearTimeout(scrollTimer.value)
    scrollTimer.value = null
  }

  // 清理requestAnimationFrame
  if (updateTimer !== null) {
    cancelAnimationFrame(updateTimer)
    updateTimer = null
  }
})
</script>

<style scoped>
.chart-container {
  position: relative;
  width: 100%;
  height: 100%;
}

.chart-renderer {
  background-color: #f5f5f5;
  min-height: 400px;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  position: relative;
  overflow: hidden; /* 防止内容溢出 */
  width: 100%;
  height: 100%;
}

/* 自定义滚动条容器 */
.custom-scrollbar {
  position: absolute;
  right: 10px;
  top: 12%;
  bottom: 10%;
  width: 20px;
  z-index: 100;
  pointer-events: all;
}

/* 滚动条轨道 */
.scrollbar-track {
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.05);
  border-radius: 10px;
  border: 1px solid #ccc;
  position: relative;
}

/* 滚动条滑块 */
.scrollbar-thumb {
  position: absolute;
  left: 0;
  right: 0;
  background: linear-gradient(to right, rgba(64, 158, 255, 0.3), rgba(64, 158, 255, 0.5));
  border-radius: 10px;
  cursor: pointer;
  transition: background 0.2s;
  border: 1px solid rgba(64, 158, 255, 0.6);
}

.scrollbar-thumb:hover {
  background: linear-gradient(to right, rgba(64, 158, 255, 0.5), rgba(64, 158, 255, 0.7));
}

.scrollbar-thumb:active {
  background: linear-gradient(to right, rgba(64, 158, 255, 0.6), rgba(64, 158, 255, 0.8));
  cursor: grabbing;
}

/* 优化滚动条样式 */
:deep(.echarts-for-react) {
  width: 100% !important;
  height: 100% !important;
}
</style>